﻿using PrinterMonitorSvc.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace PrinterMonitorSvc.Ext
{
    /// <summary>
    /// object扩展方法
    /// </summary>
    public static class ObjectExt
    {
        #region 日期转换
        /// <summary>
        /// 转换为日期
        /// </summary>
        /// <param name="data">数据</param>
        public static DateTime ToDate(this object data)
        {
            if (data == null)
                return DateTime.MinValue;
            DateTime result;
            return DateTime.TryParse(data.ToString(), out result) ? result : DateTime.MinValue;
        }

        /// <summary>
        /// 转换为可空日期
        /// </summary>
        /// <param name="data">数据</param>
        public static DateTime? ToDateOrNull(this object data)
        {
            if (data == null)
                return null;
            DateTime result;
            bool isValid = DateTime.TryParse(data.ToString(), out result);
            if (isValid)
                return result;
            return null;
        }

        #endregion

        #region 布尔转换
        /// <summary>
        /// 转换为布尔值
        /// </summary>
        /// <param name="data">数据</param>
        public static bool ToBool(this object data)
        {
            if (data == null)
                return false;
            return GetBool(data) ?? false;
        }

        /// <summary>
        /// 转换为可空布尔值
        /// </summary>
        /// <param name="data">数据</param>
        public static bool? ToBoolOrNull(this object data)
        {
            if (data == null)
                return null;
            return GetBool(data);
        }

        /// <summary>
        /// 获取布尔值
        /// </summary>
        private static bool? GetBool(this object data)
        {
            switch (data.ToString().Trim().ToLower())
            {
                case "false":
                    return false;
                case "true":
                    return true;
                case "0":
                    return false;
                case "1":
                    return true;
                case "是":
                    return true;
                case "否":
                    return false;
                case "yes":
                    return true;
                case "no":
                    return false;
                default:
                    bool result;
                    bool isValid = bool.TryParse(data.ToString(), out result);
                    if (isValid)
                    {
                        return result;
                    }
                    return null;
            }
        }

        #endregion

        #region 枚举转换
        /// <summary>
        /// 转换为枚举
        /// </summary>
        /// <typeparam name="TEnum">枚举类型</typeparam>
        /// <param name="data">枚举的Key或Value值</param>
        /// <returns></returns>
        public static TEnum ToEnum<TEnum>(this object data) where TEnum : struct
        {
            if (data == null || !typeof(TEnum).IsEnum)
            {
                return default(TEnum);
            }
            TEnum result;
            return Enum.TryParse(data.ToString(), true, out result) ? result : default(TEnum);
        }
        #endregion

        #region 是否为空(包含空白字符串)
        /// <summary>
        /// 是否为空(包含空白字符串)
        /// </summary>
        /// <param name="value">值</param>
        public static bool IsEmpty(this object value)
        {
            return null == value || string.IsNullOrWhiteSpace(value.ToString());
        }
        #endregion

        #region 转换成字典
        /// <summary>
        /// 转换成字典
        /// </summary>
        /// <param name="value">值</param>
        /// <returns></returns>
        public static Dictionary<string, object> ToDictionary(this object value)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            var props = value.GetType().GetProperties();
            foreach (var p in props)
            {
                dictionary.Add(p.Name, p.GetValue(value));
            }
            return dictionary;
        }
        #endregion

        #region 深拷贝对象
        /// <summary>
        /// 深拷贝对象（对象需要配置可序列化特性[Serializable]）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T ToDeepClone<T>(this object value) where T : class
        {
            using (Stream objectStream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, value);
                objectStream.Seek(0, SeekOrigin.Begin);
                return formatter.Deserialize(objectStream) as T;
            }
        }
        #endregion

        #region 获取虚拟路径的物理地址
        /// <summary>
        /// 获取虚拟路径的物理地址
        /// </summary>
        /// <param name="virtualPath">虚拟路径</param>
        /// <returns>物理地址</returns>
        public static string ToPhysicalPath(this string virtualPath)
        {
            return FileHelper.MapVirtualPath(virtualPath);
        }
        #endregion
    }
}
